/* Copyright 2018-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */
package com.github.drinkjava2.gosqlgo;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.github.drinkjava2.gosqlgo.util.ClassExistCacheUtils;
import com.github.drinkjava2.gosqlgo.util.GsgStrUtils;

/**
 * DeployTool extract all SQL and Java in html or .js files to server side, and
 * reverse.
 * 
 * @author Yong Zhu
 * @since 1.0.0
 */
public class GoSqlGoEnv {// NOSONAR

	private static final Map<String, Class<?>> gsgTemplates = new HashMap<String, Class<?>>();

	public static void registerGsgTemplate(String gsgMethod, Class<?> templateClass) {
		gsgTemplates.put(gsgMethod, templateClass);
	}

	private static final String DEPLOY_PACKAGE; // deploy package name, store dynamic generated classed

	private static final String TEMPLATE_PACKAGE; // template package name to store GoSqlGo template classes

	private static final String PROJECT_ROOT_FOLDER; // absolute path of deploy package

	private static final boolean PRODUCT; // if is product, reject compile files sent from front end

	private static final boolean JAVA_FILE_EXPORT; // if export java class source file in classes/.../deploy folder

	private static final String NODE_JS_URL; // Node.js server url setting

	static {
		InputStream is = DeployTool.class.getClassLoader().getResourceAsStream("GoSqlGo.properties");
		if (is == null) {
			System.err.println("Error: Config file GoSqlGo.properties not found.");
			System.exit(0);
		}
		Properties prop = new Properties();
		try {
			prop.load(is);
			DEPLOY_PACKAGE = prop.getProperty("deploy_package");
			TEMPLATE_PACKAGE = prop.getProperty("template_package");
			NODE_JS_URL = prop.getProperty("node_js_url");

			String stage = prop.getProperty("stage");
			if ("product".equalsIgnoreCase(stage))
				PRODUCT = true;
			else if ("develop".equalsIgnoreCase(stage))
				PRODUCT = false;
			else
				throw new IllegalArgumentException("In GoSqlGo.properties, stage can only be develop or product");

			if ("true".equalsIgnoreCase(prop.getProperty("java_file_export")))
				JAVA_FILE_EXPORT = true;
			else
				JAVA_FILE_EXPORT = false;

			String newFilePath = new File("").getAbsolutePath();
			newFilePath = GsgStrUtils.substringBefore(newFilePath, "\\target");
			PROJECT_ROOT_FOLDER = GsgStrUtils.substringBefore(newFilePath, "/target");
		} catch (Exception e) {
			throw new IllegalArgumentException(e);
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Return class stored in deploy package, if not found, return null
	 */
	public static Class<?> findStoredClass(String sqlJavaPiece) {
		if (sqlJavaPiece == null)
			return null;
		if (!GsgStrUtils.isLegalClassName(sqlJavaPiece))
			return null;
		return ClassExistCacheUtils.checkClassExist(
				new StringBuilder(GoSqlGoEnv.getDeployPackage()).append(".").append(sqlJavaPiece).toString());
	}

	public static String getClassesDeployFolder() {
		return getClassLoaderFolder() + "/" + GsgStrUtils.replace(DEPLOY_PACKAGE, ".", "/");
	}

	public static String getSrcDeployFolder() {
		return getProjectRootFolder() + "/src/main/java/" + GsgStrUtils.replace(DEPLOY_PACKAGE, ".", "/");
	}

	public static String getSrcWebappFolder() {
		return getProjectRootFolder() + "/src/main/webapp";

	}

	public static String getClassLoaderFolder() {
		String path = Thread.currentThread().getContextClassLoader().getResource("").toString();
		path = GsgStrUtils.replaceFirst(path, "file:/", "");
		path = GsgStrUtils.replaceFirst(path, "file:", "");
		if (path.endsWith("/") || path.endsWith("\\"))
			path = path.substring(0, path.length() - 1);
		return path;
	}

	public static void testPath() {
		System.out.println("ClassLoaderFolder=" + getClassLoaderFolder());
		System.out.println("SrcDeployFolder=" + getSrcDeployFolder());
		System.out.println("SrcWebappFolder=" + getSrcWebappFolder());
		System.out.println("ClassesDeployFolder=" + getClassesDeployFolder());

		/*- 
		In Eclipse(undertow pom): 
		ClassLoaderFolder=F:/gproj/gosqlgo/gosqlgo/demo/gsg-jbooox/target/test-classes
		SrcDeployFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox/src/main/java/com/demo/deploy
		SrcWebappFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox/src/main/webapp
		ClassesDeployFolder=F:/gproj/gosqlgo/gosqlgo/demo/gsg-jbooox/target/test-classes/com/demo/deploy
		
		in undertow/jetty/tomcat embedded.bat  
		ClassLoaderFolder=F:/gproj/gosqlgo/gosqlgo/demo/gsg-jbooox/target/classes
		SrcDeployFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox\target\classes/src/main/java/com/demo/deploy
		SrcWebappFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox\target\classes/src/main/webapp
		ClassesDeployFolder=F:/gproj/gosqlgo/gosqlgo/demo/gsg-jbooox/target/classes/com/demo/deploy
		
		in run_tomcat_local.bat 
		ClassLoaderFolder=C:/tomcat8/webapps/ROOT/WEB-INF/classes
		SrcDeployFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox\target/src/main/java/com/demo/deploy
		SrcWebappFolder=F:\gproj\gosqlgo\gosqlgo\demo\gsg-jbooox\target/src/main/webapp
		ClassesDeployFolder=C:/tomcat8/webapps/ROOT/WEB-INF/classes/com/demo/deploy 
		
		By hand start tomcat: 
		ClassLoaderFolder=C:/tomcat8/webapps/ROOT/WEB-INF/classes
		SrcDeployFolder=C:\tomcat8\bin/src/main/java/com/demo/deploy
		SrcWebappFolder=C:\tomcat8\bin/src/main/webapp
		ClassesDeployFolder=C:/tomcat8/webapps/ROOT/WEB-INF/classes/com/demo/deploy 
		*/
	}

	public static void main(String[] args) {
		testPath();
	}
	// ==========getter & setter =============

	public static Map<String, Class<?>> getGsgtemplates() {
		return gsgTemplates;
	}

	public static String getDeployPackage() {
		return DEPLOY_PACKAGE;
	}

	public static String getTemplatePackage() {
		return TEMPLATE_PACKAGE;
	}

	public static String getProjectRootFolder() {
		return PROJECT_ROOT_FOLDER;
	}

	public static boolean isProduct() {
		return PRODUCT;
	}

	public static boolean isJavaFileExport() {
		return JAVA_FILE_EXPORT;
	}

	public static String getNodeJsUrl() {
		return NODE_JS_URL;
	}

}
